package com.example.demoddd.domain.userauth.services;


import com.example.demoddd.domain.userauth.model.entity.StPermissionSysTemp;
import com.example.demoddd.domain.userauth.model.entity.StPermissions;
import com.example.demoddd.domain.userauth.repositorise.StPermissionSysTempMapper;
import com.example.demoddd.domain.userauth.repositorise.StPermissionsMapper;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationContext;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.example.demoddd.domain.userauth.model.entity.table.StPermissionsTableDef.ST_PERMISSIONS;
import static com.example.demoddd.domain.userauth.model.entity.table.StRolePermissionsTableDef.ST_ROLE_PERMISSIONS;
import static com.example.demoddd.domain.userauth.model.entity.table.StRolesTableDef.ST_ROLES;
import static com.example.demoddd.domain.userauth.model.entity.table.StUserRolesTableDef.ST_USER_ROLES;
import static com.example.demoddd.domain.userauth.model.entity.table.StUserTableDef.ST_USER;

/**
 * 用户领域服务
 */
@Service
@RequiredArgsConstructor
public class PermissionService extends ServiceImpl<StPermissionsMapper, StPermissions> {
    private final StPermissionSysTempMapper stPermissionSysTempMapper;
    private final ApplicationContext applicationContext;

    public List<String> queryPermissionsByUserid(long userId) {
        QueryWrapper queryWrapper = QueryWrapper.create();
        queryWrapper.select(ST_PERMISSIONS.PERMISSION_VAL)
                .from(ST_PERMISSIONS)
                .innerJoin(ST_ROLE_PERMISSIONS).on(ST_ROLE_PERMISSIONS.PERMISSION_ID.eq(ST_PERMISSIONS.PERMISSION_ID))
                .innerJoin(ST_ROLES).on(ST_ROLES.ROLE_ID.eq(ST_ROLE_PERMISSIONS.ROLE_ID))
                .innerJoin(ST_USER_ROLES).on(ST_USER_ROLES.ROLE_ID.eq(ST_ROLES.ROLE_ID))
                .innerJoin(ST_USER).on(ST_USER.USER_ID.eq(ST_USER_ROLES.USER_ID))
                .and(ST_USER.USER_ID.eq(userId));

        List<String> stPermissions = this.mapper.selectListByQueryAs(queryWrapper, String.class);
        return stPermissions;
    }


    public void refreshPreAuthorizeToPermission() {

        RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);

        //获取url与类和方法的对应信息
        Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();

        List<StPermissionSysTemp> stPermissionSysTempList = new ArrayList<>();
        for (RequestMappingInfo info : map.keySet()) {

            //获取方法上额注解
            HandlerMethod handlerMethod = map.get(info);
            PreAuthorize methodAnnotation = handlerMethod.getMethodAnnotation(PreAuthorize.class);
            if (null == methodAnnotation) {
                continue;
            }


            //过滤出权限验证的uri
            //String value = methodAnnotation.value();
            //System.out.println(value);

            //Doc注解
            Tag tag = handlerMethod.getMethodAnnotation(Tag.class);
            String tagName = null;
            if (null != tag) {
                tagName = tag.name();
            }

            //获取url的Set集合，一个方法可能对应多个url
            Set<String> patterns = info.getPatternValues();

            for (String url : patterns) {

                StPermissionSysTemp stPermissionSysTemp = new StPermissionSysTemp();

                stPermissionSysTemp.setPermissionName(tagName);
                stPermissionSysTemp.setPermissionVal(url);
                stPermissionSysTempList.add(stPermissionSysTemp);
            }
        }

        System.out.println("uri>>>>>>>>>>>");
        System.out.println(stPermissionSysTempList);

        //清空临时表
        stPermissionSysTempMapper.deleteByQuery(QueryWrapper.create().and("1=1"));

        stPermissionSysTempMapper.insertBatch(stPermissionSysTempList);
    }


    public List<StPermissions> queryall() {
        List<StPermissions> list = this.list();
        return list;
    }

}
